#pragma once

#include "network/Session.h"
#include <boost/functional/hash.hpp>

class GateServerSessionHandler;

struct GateServerGUID {
	uint32 serverId = 0;
	uint32 gateSN = 0;
	uint32 msSN = 0;
	bool operator==(const GateServerGUID& other) const {
		return serverId == other.serverId &&
			gateSN == other.gateSN &&
			msSN == other.msSN;
	}
};
namespace std {
	template <> struct hash<GateServerGUID> {
		std::size_t operator()(const GateServerGUID& arg) const {
			return boost::hash_range(
				(u32*)&arg, (u32*)((u8*)&arg + sizeof(arg)));
		}
	};
}

class GateServerSession : public Session
{
public:
	GateServerSession();
	virtual ~GateServerSession();

	virtual int HandlePacket(INetPacket *pck);
	virtual void OnShutdownSession();

	void TransPacket(uint32 sn, const INetPacket& pck);
	void TransPacket(uint32 sn, const std::string_view& data);
	void TransPacket(uint32 sn,
		const INetPacket *pcks[], size_t pck_num,
		const std::string_view datas[], size_t data_num);

	bool IsReady() const { return m_guid.serverId != 0; }
	const GateServerGUID& guid() const { return m_guid; }
	void resetGUID() { m_guid = {}; }

private:
	virtual void OnRecvPacket(INetPacket *pck);

	void TransPlayerPacket(INetPacket *pck) const;

	friend GateServerSessionHandler;
	GateServerGUID m_guid;
	uint32 m_gsIdx;
};
